package org.cybzacg.encryption.monitoring.impl;

import org.cybzacg.encryption.monitoring.PerformanceMonitor;
import org.cybzacg.encryption.monitoring.metrics.EncryptionMetrics;
import org.cybzacg.encryption.monitoring.metrics.PerformanceMetrics;
import org.cybzacg.encryption.monitoring.metrics.SecurityMetrics;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

/**
 * 默认性能监控实现
 * 提供完整的性能监控和指标收集功能
 * 
 * @author encryption team
 * @version 1.0
 */
public class DefaultPerformanceMonitor implements PerformanceMonitor {
    
    private volatile boolean enabled = true;
    
    // 指标收集器
    private final EncryptionMetrics encryptionMetrics;
    private final PerformanceMetrics performanceMetrics;
    private final SecurityMetrics securityMetrics;
    
    // 操作上下文管理
    private final Map<Long, OperationContextImpl> activeOperations = new ConcurrentHashMap<>();
    private final AtomicLong contextIdGenerator = new AtomicLong(0);
    
    /**
     * 构造函数
     */
    public DefaultPerformanceMonitor() {
        this.encryptionMetrics = new EncryptionMetrics();
        this.performanceMetrics = new PerformanceMetrics();
        this.securityMetrics = new SecurityMetrics();
    }
    
    @Override
    public OperationContext startOperation(String operationName) {
        if (!enabled) {
            return new NoOpOperationContext(operationName);
        }
        
        long contextId = contextIdGenerator.incrementAndGet();
        OperationContextImpl context = new OperationContextImpl(contextId, operationName);
        activeOperations.put(contextId, context);
        
        // 记录性能指标
        performanceMetrics.recordOperation();
        
        return context;
    }
    
    @Override
    public void endOperation(OperationContext context, boolean success) {
        if (!enabled) {
            return;
        }
        
        if (context instanceof OperationContextImpl) {
            OperationContextImpl impl = (OperationContextImpl) context;
            long duration = System.currentTimeMillis() - impl.getStartTime();
            
            // 记录性能指标
            performanceMetrics.recordResponseTime(duration);
            
            if (!success) {
                performanceMetrics.recordError();
            }
            
            // 移除活跃操作
            activeOperations.remove(impl.getContextId());
        }
    }
    
    @Override
    public void recordEncryption(String algorithm, long dataSize, long duration, boolean success) {
        if (!enabled) {
            return;
        }
        
        // 记录加密指标
        encryptionMetrics.recordEncryption(algorithm, dataSize, duration, success);
        
        // 记录性能指标
        performanceMetrics.recordResponseTime(duration);
        if (!success) {
            performanceMetrics.recordError();
        }
        
        // 记录安全指标
        if (!success) {
            securityMetrics.recordEncryptionFailure(algorithm);
        }
    }
    
    @Override
    public void recordDecryption(String algorithm, long dataSize, long duration, boolean success) {
        if (!enabled) {
            return;
        }
        
        // 记录加密指标
        encryptionMetrics.recordDecryption(algorithm, dataSize, duration, success);
        
        // 记录性能指标
        performanceMetrics.recordResponseTime(duration);
        if (!success) {
            performanceMetrics.recordError();
        }
        
        // 记录安全指标
        if (!success) {
            securityMetrics.recordDecryptionFailure(algorithm);
        }
    }
    
    @Override
    public void recordSignature(String algorithm, long dataSize, long duration, boolean success) {
        if (!enabled) {
            return;
        }
        
        // 记录加密指标
        encryptionMetrics.recordSignature(algorithm, dataSize, duration, success);
        
        // 记录性能指标
        performanceMetrics.recordResponseTime(duration);
        if (!success) {
            performanceMetrics.recordError();
        }
        
        // 记录安全指标
        if (!success) {
            securityMetrics.recordSignatureFailure(algorithm);
        }
    }
    
    @Override
    public void recordVerification(String algorithm, long dataSize, long duration, boolean success) {
        if (!enabled) {
            return;
        }
        
        // 记录加密指标
        encryptionMetrics.recordVerification(algorithm, dataSize, duration, success);
        
        // 记录性能指标
        performanceMetrics.recordResponseTime(duration);
        if (!success) {
            performanceMetrics.recordError();
        }
        
        // 记录安全指标
        if (!success) {
            securityMetrics.recordVerificationFailure(algorithm);
        }
    }
    
    @Override
    public EncryptionMetrics getEncryptionMetrics() {
        return encryptionMetrics;
    }
    
    @Override
    public PerformanceMetrics getPerformanceMetrics() {
        return performanceMetrics;
    }
    
    @Override
    public SecurityMetrics getSecurityMetrics() {
        return securityMetrics;
    }
    
    @Override
    public void resetMetrics() {
        encryptionMetrics.reset();
        performanceMetrics.reset();
        securityMetrics.reset();
        
        // 清理活跃操作
        activeOperations.clear();
        contextIdGenerator.set(0);
    }
    
    @Override
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
        if (!enabled) {
            // 清理所有活跃操作
            activeOperations.clear();
        }
    }
    
    @Override
    public boolean isEnabled() {
        return enabled;
    }
    
    /**
     * 获取活跃操作数
     * 
     * @return 活跃操作数
     */
    public int getActiveOperationCount() {
        return activeOperations.size();
    }
    
    /**
     * 获取总操作数
     * 
     * @return 总操作数
     */
    public long getTotalOperationCount() {
        return contextIdGenerator.get();
    }
    
    /**
     * 更新性能指标
     */
    public void updateMetrics() {
        if (enabled) {
            performanceMetrics.update();
        }
    }
    
    /**
     * 获取监控统计信息
     * 
     * @return 监控统计信息
     */
    public MonitorStatistics getStatistics() {
        return new MonitorStatistics(
            getTotalOperationCount(),
            getActiveOperationCount(),
            encryptionMetrics.getTotalEncryptions(),
            encryptionMetrics.getTotalDecryptions(),
            encryptionMetrics.getTotalSignatures(),
            encryptionMetrics.getTotalVerifications(),
            performanceMetrics.getTotalOperations(),
            performanceMetrics.getErrorCount(),
            securityMetrics.getSecurityViolations(),
            securityMetrics.getSecurityScore()
        );
    }
    
    @Override
    public String toString() {
        return String.format(
            "DefaultPerformanceMonitor:\n" +
            "  Enabled: %s\n" +
            "  Active Operations: %d\n" +
            "  Total Operations: %d\n" +
            "  Encryption Metrics:\n%s\n" +
            "  Performance Metrics:\n%s\n" +
            "  Security Metrics:\n%s",
            enabled, getActiveOperationCount(), getTotalOperationCount(),
            encryptionMetrics.toString(),
            performanceMetrics.toString(),
            securityMetrics.toString()
        );
    }
    
    /**
     * 操作上下文实现
     */
    private static class OperationContextImpl implements OperationContext {
        
        private final long contextId;
        private final String operationName;
        private final long startTime;
        private Object data;
        
        /**
         * 构造函数
         * 
         * @param contextId 上下文ID
         * @param operationName 操作名称
         */
        public OperationContextImpl(long contextId, String operationName) {
            this.contextId = contextId;
            this.operationName = operationName;
            this.startTime = System.currentTimeMillis();
        }
        
        @Override
        public String getOperationName() {
            return operationName;
        }
        
        @Override
        public long getStartTime() {
            return startTime;
        }
        
        @Override
        public Object getData() {
            return data;
        }
        
        @Override
        public void setData(Object data) {
            this.data = data;
        }
        
        /**
         * 获取上下文ID
         * 
         * @return 上下文ID
         */
        public long getContextId() {
            return contextId;
        }
        
        /**
         * 获取操作持续时间
         * 
         * @return 操作持续时间（毫秒）
         */
        public long getDuration() {
            return System.currentTimeMillis() - startTime;
        }
    }
    
    /**
     * 空操作上下文
     */
    private static class NoOpOperationContext implements OperationContext {
        
        private final String operationName;
        private final long startTime;
        private Object data;
        
        /**
         * 构造函数
         * 
         * @param operationName 操作名称
         */
        public NoOpOperationContext(String operationName) {
            this.operationName = operationName;
            this.startTime = System.currentTimeMillis();
        }
        
        @Override
        public String getOperationName() {
            return operationName;
        }
        
        @Override
        public long getStartTime() {
            return startTime;
        }
        
        @Override
        public Object getData() {
            return data;
        }
        
        @Override
        public void setData(Object data) {
            this.data = data;
        }
    }
    
    /**
     * 监控统计信息类
     */
    public static class MonitorStatistics {
        
        private final long totalOperations;
        private final int activeOperations;
        private final long totalEncryptions;
        private final long totalDecryptions;
        private final long totalSignatures;
        private final long totalVerifications;
        private final long performanceOperations;
        private final long totalErrors;
        private final long securityViolations;
        private final double securityScore;
        
        /**
         * 构造函数
         */
        public MonitorStatistics(long totalOperations, int activeOperations,
                                long totalEncryptions, long totalDecryptions,
                                long totalSignatures, long totalVerifications,
                                long performanceOperations, long totalErrors,
                                long securityViolations, double securityScore) {
            this.totalOperations = totalOperations;
            this.activeOperations = activeOperations;
            this.totalEncryptions = totalEncryptions;
            this.totalDecryptions = totalDecryptions;
            this.totalSignatures = totalSignatures;
            this.totalVerifications = totalVerifications;
            this.performanceOperations = performanceOperations;
            this.totalErrors = totalErrors;
            this.securityViolations = securityViolations;
            this.securityScore = securityScore;
        }
        
        public long getTotalOperations() {
            return totalOperations;
        }
        
        public int getActiveOperations() {
            return activeOperations;
        }
        
        public long getTotalEncryptions() {
            return totalEncryptions;
        }
        
        public long getTotalDecryptions() {
            return totalDecryptions;
        }
        
        public long getTotalSignatures() {
            return totalSignatures;
        }
        
        public long getTotalVerifications() {
            return totalVerifications;
        }
        
        public long getPerformanceOperations() {
            return performanceOperations;
        }
        
        public long getTotalErrors() {
            return totalErrors;
        }
        
        public long getSecurityViolations() {
            return securityViolations;
        }
        
        public double getSecurityScore() {
            return securityScore;
        }
        
        @Override
        public String toString() {
            return String.format(
                "MonitorStatistics:\n" +
                "  Total Operations: %d\n" +
                "  Active Operations: %d\n" +
                "  Crypto Operations: Enc=%d, Dec=%d, Sig=%d, Ver=%d\n" +
                "  Performance: Ops=%d, Errors=%d\n" +
                "  Security: Violations=%d, Score=%.1f/100.0",
                totalOperations, activeOperations, totalEncryptions, totalDecryptions,
                totalSignatures, totalVerifications, performanceOperations, totalErrors,
                securityViolations, securityScore
            );
        }
    }
}
